'use client';

import { useEffect, useState, useRef } from 'react';
import { useSearchParams } from 'next/navigation';
import AMapLoader from '@amap/amap-jsapi-loader';
import { show } from 'antd-mobile/es/components/dialog/show';
import styles from './ditu.module.css';

// TypeScript 声明 AMap 命名空间
declare namespace AMap {
    class Map {
        constructor(container: string | HTMLDivElement, options?: MapOptions);
        destroy(): void;
        setCenter(position: LngLat | [number, number]): void;
        setZoom(zoom: number): void;
        add(overaly: any): void; // 简化，实际应为 AMap.Overlay 或数组
        on(event: string, handler: (...args: any[]) => void): void;
        setZoomAndCenter(zoom: number, position: LngLat | [number, number], smooth: boolean, duration: number): void;
    }

    interface MapOptions {
        viewMode?: string;
        zoom?: number;
        center?: LngLat | [number, number];
        pitch?: number;
        rotateEnable?: boolean;
        pitchEnable?: boolean;
        rotation?: number;
        zooms?: [number, number];
    }

    class LngLat {
        constructor(lng: number, lat: number);
        lng: number;
        lat: number;
        distance(other: LngLat): number;
    }

    class Geolocation {
        constructor(options?: any); // 简化
        getCurrentPosition(callback: (status: string, result: any) => void): void; // 简化 result 类型
    }

    class TileLayer {
        static Traffic: any; // 简化
    }

    class MapType {
        constructor(options?: any); // 简化
    }

    class Scale {
        constructor();
    }

    class ToolBar {
        constructor();
    }

    class PlaceSearch {
        constructor(options?: any); // 简化
        setCity(city: string): void;
        search(keyword: string, callback?: (status: string, result: any) => void): void; // 简化 result 类型
    }

    class AutoComplete {
        constructor(options?: any); // 简化
        on(event: string, handler: (...args: any[]) => void): void;
    }

    class Geocoder {
        constructor(options?: any); // 简化
        getAddress(location: LngLat | [number, number], callback: (status: string, result: any) => void): void; // 简化 result 类型
        getLocation(keyword: string, callback: (status: string, result: any) => void): void; // 简化 result 类型
    }

    class Marker {
        constructor(options?: any); // 简化
        on(event: string, handler: (...args: any[]) => void): void;
    }

    class InfoWindow {
        constructor(options?: any); // 简化
        open(map: Map, position: LngLat | [number, number]): void;
    }

    class Pixel {
        constructor(x: number, y: number);
    }
}


// TypeScript 类型定义 (保留您的自定义类型，它们现在可以引用上面声明的 AMap 命名空间)
type MapInstance = AMap.Map;
type Position = { lng: number; lat: number };
type GeolocationResult = {
    position: Position;
    addressComponent: {
        adcode: string;
        province: string;
        city: string;
        district: string;
    };
    formattedAddress: string;
    pois: Array<{ name: string }>;
    accuracy?: number;
};
type ReGeocodeResult = {
    regeocode: {
        formattedAddress: string;
        pois: Array<{ name: string }>;
        addressComponent: { adcode: string };
    };
    info: string;
};
type GeocodeResult = {
    geocodes: Array<{ location: Position }>;
    info: string;
};

export default function MapComponent({ initialEndPoint }: { initialEndPoint?: string }) {
    const searchParams = useSearchParams();
    const mapRef = useRef<MapInstance | null>(null);
    const [map, setMap] = useState<MapInstance | null>(null);
    const [placeSearch, setPlaceSearch] = useState<any>(null); // AMap.PlaceSearch 类型较复杂，暂时用any
    const [isLoading, setIsLoading] = useState(true);
    const [searchKeyword, setSearchKeyword] = useState('');
    const [startPoint, setStartPoint] = useState('');
    const [endPoint, setEndPoint] = useState(initialEndPoint || '');
    const [driving, setDriving] = useState<any>(null); // AMap.Driving 类型较复杂，暂时用any
    const [currentPosition, setCurrentPosition] = useState<Position | null>(null);
    const [loadedAMap, setLoadedAMap] = useState<any>(null); // 新增狀態儲存載入的 AMap 物件

    // 處理地址參數
    useEffect(() => {
        const addressParam = searchParams.get('address');
        if (addressParam) {
            const decodedAddress = decodeURIComponent(addressParam);
            setEndPoint(decodedAddress);
            if (loadedAMap && map) {
                // 直接搜索目標地址
                const geocoder = new loadedAMap.Geocoder({ city: '全国' });
                geocoder.getLocation(decodedAddress, (status: string, result: GeocodeResult) => {
                    if (status === 'complete' && result.info === 'OK' && result.geocodes?.[0]?.location) {
                        const location = result.geocodes[0].location;
                        // 直接設置為中心點
                        map.setZoomAndCenter(15, [location.lng, location.lat], true, 1000);

                        const marker = new loadedAMap.Marker({
                            position: location,
                            title: decodedAddress,
                            map: map
                        });
                        const infoWindow = new loadedAMap.InfoWindow({
                            content: `<div class="${styles.infoWindow}">
                                      <h3>${decodedAddress}</h3>
                                      <p>經度：${location.lng}</p>
                                      <p>緯度：${location.lat}</p>
                                    </div>`,
                            offset: new loadedAMap.Pixel(0, -30)
                        });
                        infoWindow.open(map, [location.lng, location.lat]);
                    }
                });
            }
        }
    }, [searchParams, loadedAMap, map]);

    // 初始化地图
    const initMap = (AMap: any): any => {
        // 尝试获取用户当前位置
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(
                (position) => {
                    const { latitude, longitude } = position.coords;
                    const mapInstance = new AMap.Map('container', {
                        viewMode: '3D',
                        zoom: 11,
                        center: [longitude, latitude] as [number, number], // 使用当前位置
                        pitch: 50,
                        rotateEnable: true,
                        pitchEnable: true,
                        rotation: -15,
                        zooms: [2, 20],
                    });
                    setMap(mapInstance); // 更新 map 状态
                    initPlugins(AMap, mapInstance); // 初始化插件
                },
                (error) => {
                    console.error('获取当前位置失败:', error);
                    // 如果获取当前位置失败，使用默认位置
                    const mapInstance = new AMap.Map('container', {
                        viewMode: '3D',
                        zoom: 11,
                        center: [116.397428, 39.90923] as [number, number], // 默认北京位置
                        pitch: 50,
                        rotateEnable: true,
                        pitchEnable: true,
                        rotation: -15,
                        zooms: [2, 20],
                    });
                    setMap(mapInstance); // 更新 map 状态
                    initPlugins(AMap, mapInstance); // 初始化插件
                }
            );
        } else {
            console.error('浏览器不支持地理位置');
            // 如果浏览器不支持地理位置，使用默认位置
            const mapInstance = new AMap.Map('container', {
                viewMode: '3D',
                zoom: 11,
                center: [116.397428, 39.90923] as [number, number], // 默认北京位置
                pitch: 50,
                rotateEnable: true,
                pitchEnable: true,
                rotation: -15,
                zooms: [2, 20],
            });
            setMap(mapInstance); // 更新 map 状态
            initPlugins(AMap, mapInstance); // 初始化插件
        }
    };

    // 初始化插件
    const initPlugins = (AMap: any, mapInstance: any) => {
        // 交通图层
        const traffic = new AMap.TileLayer.Traffic({ autoRefresh: true, interval: 180 });
        mapInstance.add(traffic);

        // 定位控制
        const geolocation = new AMap.Geolocation({
            enableHighAccuracy: true,
            timeout: 10000,
            offset: [10, 60] as [number, number],
            zoomToAccuracy: true,
            position: 'LB',
            panToLocation: true,
            getCityWhenFailed: true,
        });
        mapInstance.addControl(geolocation);

        geolocation.getCurrentPosition((status: string, result: GeolocationResult | { message?: string; info?: string }) => {
            if (status === 'complete') {
                const geolocationResult = result as GeolocationResult;
                if (!isValidPosition(geolocationResult.position)) {
                    console.error('获取的经纬度无效:', geolocationResult.position);
                    return;
                }
                console.log('定位成功:', geolocationResult.position);
                onComplete(geolocationResult);
            } else {
                console.error('定位失败:', status, result);
                onError(result as { message?: string });
            }
        });

        // 其他控件
        mapInstance.addControl(new AMap.MapType({ defaultType: 0 }));
        mapInstance.addControl(new AMap.Scale());
        mapInstance.addControl(new AMap.ToolBar());

        // 搜索功能
        const placeSearchInstance = new AMap.PlaceSearch({
            pageSize: 3,
            pageIndex: 1,
            city: '全国',
            map: mapInstance,
            panel: 'panel'
        });
        setPlaceSearch(placeSearchInstance);

        // 自动完成
        const searchAutoComplete = new AMap.AutoComplete({
            city: '全国',
            input: 'searchInput',
        });
        searchAutoComplete.on('select', (e: { poi: { adcode: string; name: string } }) => {
            placeSearchInstance.setCity(e.poi.adcode);
            placeSearchInstance.search(e.poi.name);
        });

        const endPointAutoComplete = new AMap.AutoComplete({
            city: '全国',
            input: 'endPointInput',
        });
        endPointAutoComplete.on('select', (e: { poi: { name: string } }) => {
            setEndPoint(e.poi.name);
        });

        // 驾车路线
        setDriving(new AMap.Driving({ map: mapInstance, panel: 'routePanel', showTraffic: true }));

        setIsLoading(false);
    };

    // 验证经纬度是否有效
    const isValidPosition = (pos: Position | null): pos is Position => {
        return !!pos &&
            !isNaN(pos.lng) && !isNaN(pos.lat) &&
            Math.abs(pos.lng) <= 180 &&
            Math.abs(pos.lat) <= 90;
    };

    // 定位成功回调
    const onComplete = async (data: GeolocationResult) => {
        console.log('定位成功:', data);
        if (map && data.position) {
            map.setCenter([data.position.lng, data.position.lat] as [number, number]);

            // 检查定位准确度
            if (data.accuracy !== undefined && data.accuracy > 100) { // 假设大于100米为较低准确度
                console.warn('定位准确度较低:', data.accuracy, '米');
                show({
                    content: `定位成功，但准确度较低 (${data.accuracy} 米)。请在开阔地带尝试以获得更准确的位置。`,
                    actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
                });
            }
        }
        setCurrentPosition(data.position);

        const buildingName = await getBuildingName(loadedAMap, data.position);
        setStartPoint(buildingName || '未知位置');
    };

    // 获取建筑名称
    const getBuildingName = (AMap: any, position: Position): Promise<string | null> => {
        return new Promise((resolve) => {

            if (!isValidPosition(position)) {
                resolve(null);
                return;
            }
            // 確保 loadedAMap 已經載入
            if (!loadedAMap) {
                resolve(null);
                return;
            }
            // 解除 Geocoder 的註釋並使用 loadedAMap
            const geocoder = new loadedAMap.Geocoder({ city: '全国', radius: 1000 });
            geocoder.getAddress(position, (status: string, result: ReGeocodeResult) => {
                if (status === 'complete' && result.info === 'OK') {
                    resolve(result.regeocode.pois?.[0]?.name || result.regeocode.formattedAddress);
                } else {
                    console.error('反向地理编码失败:', result);
                    resolve(null);
                }
            });
        });
    };

    // 定位失败回调
    const onError = (data: { message?: string; info?: string; }) => { // 更新类型以匹配可能的 result 结构
        console.error('定位失败:', data);
        let errorMessage = '定位失败，请检查网络或权限设置。';
        if (data.message) {
            errorMessage = `定位失败: ${data.message}`;
        } else if (data.info) { // 有些错误信息可能在 info 属性中
            errorMessage = `定位失败: ${data.info}`;
        }

        if (errorMessage.includes(' denied')) { // 检查是否是权限被拒绝
            errorMessage += ' 请在浏览器设置中允许获取您的位置信息。';
        }


        show({
            content: errorMessage,
            actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
        });
    };

    // 搜索地点
    const handleSearch = () => {
        if (!searchKeyword.trim()) {
            show({
                content: '請輸入搜索關鍵詞。',
                actions: [{ key: 'close', text: '關閉', onClick: () => { } }],
            });
            return;
        }

        if (!loadedAMap) {
            show({
                content: '地圖庫尚未載入完成，請稍後再試。',
                actions: [{ key: 'close', text: '關閉', onClick: () => { } }],
            });
            return;
        }

        const geocoder = new loadedAMap.Geocoder({ city: '全国' });
        geocoder.getLocation(searchKeyword, (status: string, result: GeocodeResult) => {
            if (status === 'complete' && result.info === 'OK' && result.geocodes?.[0]?.location) {
                const location = result.geocodes[0].location;
                console.log('搜索地址的经纬度:', location);

                if (map) {
                    map.setCenter([location.lng, location.lat] as [number, number]);
                    map.setZoom(15); // 設置適當的縮放級別
                }

                const marker = new loadedAMap.Marker({
                    position: location,
                    title: searchKeyword,
                    map: map
                });

                // 添加信息窗體
                const infoWindow = new loadedAMap.InfoWindow({
                    content: `<div class="${styles.infoWindow}">
                              <h3>${searchKeyword}</h3>
                              <p>經度：${location.lng}</p>
                              <p>緯度：${location.lat}</p>
                            </div>`,
                    offset: new loadedAMap.Pixel(0, -30)
                });
                infoWindow.open(map, [location.lng, location.lat]);

            } else {
                console.error('地理编码失败:', result);
                show({
                    content: '無法找到該地址，請檢查輸入是否正確。',
                    actions: [{ key: 'close', text: '關閉', onClick: () => { } }],
                });
            }
        });
    };

    // 路线规划
    const handleRoutePlan = () => {
        // 检查终点是否为空
        if (!endPoint) {
            show({
                content: '请输入终点。',
                actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
            });
            return;
        }

        // 如果起点输入框为空，检查当前位置是否存在
        if (!searchKeyword.trim() && !currentPosition) {
            show({
                content: '无法确定起点位置，请在搜索框输入起点或等待定位成功。',
                actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
            });
            return;
        }


        if (!driving) {
            console.error('路线规划实例未初始化');
            return;
        }

        // 在使用 AMap 之前檢查 loadedAMap 是否已載入
        if (!loadedAMap) {
            show({
                content: '地圖庫尚未載入完成，請稍后再次嘗試。',
                actions: [{ key: 'close', text: '關閉', onClick: () => { } }],
            });
            return;
        }

        driving.clear();

        const geocoder = new loadedAMap.Geocoder({ city: '全国' });

        // 獲取終點的經緯度
        geocoder.getLocation(endPoint, (status: string, result: GeocodeResult) => {
            if (status === 'complete' && result.info === 'OK' && result.geocodes?.[0]?.location) {
                const endLocation = result.geocodes[0].location;
                console.log('终点经纬度:', endLocation);

                let startLocation: Position | null = null;

                // 根据 searchKeyword 是否为空来确定起点
                if (searchKeyword.trim()) {
                    // 如果 searchKeyword 不为空，使用 Geocoder 获取起点经纬度
                    geocoder.getLocation(searchKeyword, (startStatus: string, startResult: GeocodeResult) => {
                        if (startStatus === 'complete' && startResult.info === 'OK' && startResult.geocodes?.[0]?.location) {
                            startLocation = startResult.geocodes[0].location;
                            console.log('起点经纬度 (搜索框):', startLocation);
                            // 执行路线规划
                            driving.search(
                                [startLocation.lng, startLocation.lat] as [number, number],
                                [endLocation.lng, endLocation.lat] as [number, number],
                                (routeStatus: string) => {
                                    console.log('路线规划结果:', routeStatus);
                                    if (routeStatus !== 'complete') {
                                        show({
                                            content: '路线规划失败:请检查输入的地点是否正确。',
                                            actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
                                        });
                                    } else if (driving.getRoute() && driving.getRoute().length === 0) {
                                        show({
                                            content: '無法規劃到該終點的路線，請檢查輸入是否正確。',
                                            actions: [{ key: 'close', text: '關閉', onClick: () => { } }],
                                        });
                                    }
                                }
                            );
                        } else {
                            console.error('起点地理编码失败 (搜索框):', startResult);
                            show({
                                content: '无法找到该起点地址，请检查输入是否正确。',
                                actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
                            });
                        }
                    });
                } else {
                    // 如果 searchKeyword 为空，使用当前位置作为起点
                    startLocation = currentPosition;
                    console.log('起点经纬度 (当前位置):', startLocation);
                    // 执行路线规划 (如果 currentPosition 存在且有效)
                    if (startLocation && isValidPosition(startLocation)) {
                        driving.search(
                            [startLocation.lng, startLocation.lat] as [number, number],
                            [endLocation.lng, endLocation.lat] as [number, number],
                            (routeStatus: string) => {
                                console.log('路线规划结果:', routeStatus);
                                if (routeStatus !== 'complete') {
                                    show({
                                        content: '路线规划失败:请检查输入的地点是否正确。',
                                        actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
                                    });
                                } else if (driving.getRoute() && driving.getRoute().length === 0) {
                                    show({
                                        content: '無法規劃到該終點的路線，請檢查輸入是否正確。',
                                        actions: [{ key: 'close', text: '關閉', onClick: () => { } }],
                                    });
                                }
                            }
                        );
                    } else {
                        // 这种情况理论上在前面的检查已经排除，但为了严谨，再次处理
                        show({
                            content: '无法确定起点位置，请在搜索框输入起点或等待定位成功。',
                            actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
                        });
                    }
                }


            } else {
                console.error('终点地理编码失败:', result);
                show({
                    content: '无法找到该终点地址，请检查输入是否正确。',
                    actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
                });
            }
        });
    };

    // 初始化地图
    useEffect(() => {
        if (typeof window !== 'undefined') {
            // @ts-ignore AMap安全配置全局变量
            window._AMapSecurityConfig = {
                securityJsCode: '88d2940e7ea105792a0375861363e701'
            };

            AMapLoader.load({
                key: '6ee7852b81007eaa18ecff7d9acdd2f9',
                version: '2.0',
                plugins: [
                    'AMap.Scale', 'AMap.ToolBar', 'AMap.PlaceSearch',
                    'AMap.Driving', 'AMap.MapType', 'AMap.Geolocation',
                    'AMap.AutoComplete', 'AMap.Geocoder'
                ]
            })
                .then((AMap) => {
                    setLoadedAMap(AMap); // 儲存載入的 AMap 物件
                    const mapInstance = initMap(AMap);
                    setMap(mapInstance);
                    initPlugins(AMap, mapInstance);
                })
                .catch((error) => {
                    console.error('高德地图加载失败:', error);
                    show({
                        content: '地图加载失败，请稍后重试。',
                        actions: [{ key: 'close', text: '关闭', onClick: () => { } }],
                    });
                    setIsLoading(false);
                });
        }

        return () => {
            if (map) {
                map.destroy();
            }
        };
    }, []);

    // 修改 useEffect 以在地址參數存在時自動搜索
    useEffect(() => {
        if (searchKeyword && loadedAMap && map) {
            handleSearch();
        }
    }, [searchKeyword, loadedAMap, map]);

    return (
        <div className={styles.container}>
            {isLoading && <div className={styles.loading}>地图加载中...</div>}
            <div
                className={styles.backButton}
                onClick={() => window.history.back()}  // 点击返回上一页
            >
                &lt; 返回
            </div>
            <div className={styles.searchBox}>
                <input
                    id='searchInput'
                    type="text"
                    placeholder="请输入搜索地点"
                    value={searchKeyword}
                    onChange={(e) => setSearchKeyword(e.target.value)}
                />
                <button onClick={handleSearch}>搜索</button>
            </div>
            <div className={styles.routeBox}>

                <input
                    id="endPointInput"
                    type="text"
                    placeholder="请输入终点"
                    value={endPoint}
                    onChange={(e) => setEndPoint(e.target.value)}
                />
                <button onClick={handleRoutePlan}>驾车路线规划</button>
            </div>
            <div id="container" className={styles.map}></div>
            <div id="panel" className={styles.panel}></div>
            <div id="routePanel" className={styles.routePanel}></div>
        </div>
    );
}
